/***************************************************************************//**
 * @file softwareMultiTimer.h
 * @brief for low power timer decommand，建议MultiTimer实例分配在固定的.c，方便分配handle句柄
 * @author ze .
 * @date  2022/6/30.
 * @copyright Copyright 
 ******************************************************************************/

#ifndef _SOFTWAREMULTITIMER_H_
#define _SOFTWAREMULTITIMER_H_

#include <stdint.h>
#include "MultiTimer.h"
#include "bsp_rtc.h"
typedef enum // map to the struct array, so must be 0 1 2 3 4 ...
{
    EN_LP_HARD_TIMER_EM3_SYS_RTC = 0, //Low power, sys RTC EM3 compare0, for sensor logic use
    EN_LP_HARD_TIMER_EM3_SYS_RTC_1 = 1,//Low power,sys RTC EM3 compare1, for sensor logic use
    EN_LP_HARD_TIMER_ACTIVE_TIMER0 = 3, //normal timer
    EN_LP_HARD_TIMER_MAX
}LP_HARD_TIMER_TYPE_E;

#define READ_BU_RTC_COUNT()    BURTC_CounterGet() //To Do 待定义，返回U32,READ_BU_RTC_COUNT仅供协议栈内部使用，外部禁止使用，RTC COUNT可能会因校准而随机增大或减小
#define READ_SYS_RTC_COUNT()   sl_sysrtc_get_counter()

#define EN_LP_HARD_TIMER_EM4_BU_RTC  2 //BU RTC用作系统时间同步,仅协议库内部MAC层使用，外部不可调用.

typedef union 
{
    /* data */
    struct 
    {
        uint32_t dwCounter;
        uint32_t dwCarryTime; // liittle endian, when dwCounter overflow, the carryTime ++;
    }rtcTime32;

    struct 
    {
        uint16_t   pwCounter[2];  //
        uint32_t  dwCarryTime; //  TBD, test the alignment
    }rtcTime16;

    uint64_t dlSysTick;

}SYS_TICK_TIME_U;

/**
 * @brief Start the timer work, add the handle into work list.若isCriticalProtect == 0，则该函数仅能从while函数调用
 * 
 * @param eType in target hardTimer
 * @param timer in target handle strcut.
 * @param timing in Set the start time.
 * @param callback in deadline callback.
 * @param userData in user data.
 * @param isRepeatCheck 是否对链表内重复的数据进行检测，否 以节约时间
 * @return int >=0: success,insert idx, -1: fail.
 */
int softwareMultiTimerStart(LP_HARD_TIMER_TYPE_E eType, MultiTimer* timer, uint32_t timing, MultiTimerCallback_t callback, void* userData,uint8_t isRepeatCheck);

/**
 * @brief Start the timer work, add the handle into work list.若isCriticalProtect == 0，则该函数仅能从while函数调用
 * 
 * @param eType in target hardTimer
 * @param timer in target handle strcut.
 * @param deadline in Set the deadline 结束的时间点 时刻，用于时分多址.TBD 确保deadline时间应远大于sysTick时间，若deadline小于将产生严重后果
 * @param callback in deadline callback.
 * @param userData in user data.
 * @param isRepeatCheck 是否对链表内重复的数据进行检测，否 以节约时间
 * @return int >=0: success,insert idx, -1: fail.
 */
int softwareMultiTimeDeadlineStart(LP_HARD_TIMER_TYPE_E eType, MultiTimer* timer, uint64_t deadline, MultiTimerCallback_t callback, void* userData,uint8_t isRepeatCheck);

/**
 * @brief Stop the timer work, remove the handle off work list.若isCriticalProtect == 0，则该函数仅能从while函数调用
 * 
 * @param eType in target hardTimer
 * @param timer target handle strcut.
 * @param isCallbackExpire 是否直接回调溢出函数
 * @return int 0: success, -1: fail.
 */
int softwareMultiTimerStop(LP_HARD_TIMER_TYPE_E eType, MultiTimer* timer,uint8_t isCallbackExpire);

/**
 * @brief Stop the timer work, remove all the handling work list.若isCriticalProtect == 0，则该函数仅能从while函数调用
 * 
 * @param eType in target hardTimer
 * @return int 0: success, -1: fail.
 */
int softwareMultiTimerStopAll(LP_HARD_TIMER_TYPE_E eType);

/**
 * @brief 
 * 
 * @param eType in target hardTimer
 * @param timer target handle strcut.
 * @return int >=0: idx, -1: fail.TBD, check the eTyp
 */
int softwareMultiTimerFind(LP_HARD_TIMER_TYPE_E eType, MultiTimer* timer);

/**
 * @brief 运维使用，巡检该定时模块是否有异常，如重复节点闭环， 未开启定时器中断等；
 * 
 * @param eType in target hardTimer
 * @return int 0 ok，-1,-2异常码 TBD！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
 */
int softwareMultiTimerFaultDetect(LP_HARD_TIMER_TYPE_E eType);

/**
 * @brief Check the timer expried and call callback. 若isCriticalProtect == 0，则该函数仅能从while函数调用，若==1 在定时器中断调用后，建议每5ms在while也调用1次，不能太频繁.
 * 
 * @param eType in target hardTimer
 * @return int left time expires.
 */
int softwareMultiTimerExpiredCheck(LP_HARD_TIMER_TYPE_E eType);

/**
 * @brief software calibrate, for BuRtc only, 仅BuRTC用做时间同步的定时器
 * 
 * @param eType in target hardTimer
 * @param dwCalibrateValue in to calibrate value, max value 0 —— 0x00FFFFFF, 0x1FF=501s. when HUB ack packet received, the syncClock calibrate.
 * @param calibrateDirect 1 for +; 0 for -
 * @return int
 **/
int softwareMultiTimerCalibrate(LP_HARD_TIMER_TYPE_E eType, uint32_t dwCalibrateValue, uint8_t calibrateDirect); //TBD

/**
 * @brief get the Timer list head, for debug
 * 
 * @param eType in target hardTimer
 * @return MultiTimer*  listHead
 */
MultiTimer* getSoftwareMultiTimerListHead(LP_HARD_TIMER_TYPE_E eType);

/**
 * @brief get the Timer tick, for debug
 * 
 * @param eType in target hardTimer
 * @return SYS_TICK_TIME_U  the current timer tick.
 */
SYS_TICK_TIME_U getSoftwareTimerTick(LP_HARD_TIMER_TYPE_E eType);



#endif
